



#ifndef _PDF_CFF_DECODER_H_
#define _PDF_CFF_DECODER_H_

#include <wx/dynarray.h>
#include <wx/string.h>
#include <wx/mstream.h>
#include <wx/wfstream.h>

#include "wx/pdfdocdef.h"
#include "wx/pdfarraytypes.h"
#include "wx/pdfcffindex.h"

// Forward declaration of internal classes
class wxPdfCffFontObject;

/// Class representing CFF decoder for charstrings of type 1 and 2. (For internal use only)
class WXDLLIMPEXP_PDFDOC wxPdfCffDecoder
{
public:
  /// Default constructor
  wxPdfCffDecoder();

  /// Constructor
  
  wxPdfCffDecoder(wxPdfCffIndexArray* globalSubrIndex,
                  wxPdfSortedArrayInt* hGlobalSubrsUsed,
                  wxArrayInt* lGlobalSubrsUsed);

  /// Default destructor
  virtual ~wxPdfCffDecoder();

  /// Get character width and composites
  
  bool GetCharWidthAndComposite(wxPdfCffIndexElement& charstring, int& width, bool& isComposite, int& bchar, int& achar);

  /// Calculate the bias
  
  int CalcBias(int nSubrs);

  /// Read a subroutine from an input stream
  
  void ReadASubr(wxInputStream* stream, int begin, int end,
                 int globalBias, int localBias, 
                 wxPdfSortedArrayInt& hSubrsUsed, wxArrayInt& lSubrsUsed,
                 wxPdfCffIndexArray& localSubIndex);

protected:
  /// Read a byte from an input stream
  unsigned char ReadByte(wxInputStream* stream);

  /// Read a short integer from an input stream
  short ReadShort(wxInputStream* stream);

  /// Read an integer from an input stream
  int ReadInt(wxInputStream* stream);

    void HandleStack();

  /// Get the type of the last operator on stack
  int StackOpp();

    void EmptyStack();

    void PopStack();

    void PushStack();

    void ReadCommand(wxInputStream* stream);

  /// Calculate the hints
  int CalcHints(wxInputStream* stream, int begin, int end, int globalBias, int localBias, wxPdfCffIndexArray& localSubIndex);

private:
  wxInputStream*        m_stream;              
  wxPdfCffIndexArray*   m_globalSubrIndex;     
  int                   m_charstringType;      
  wxString              m_key;                 ///< command key word
  wxPdfCffFontObject*   m_args;                ///< argument stack
  int                   m_argCount;            
  int                   m_globalBias;          ///< The bias for the global subroutines
  int                   m_numHints;            
  wxPdfSortedArrayInt*  m_hGlobalSubrsUsed;    ///< A HashMap for keeping the Global subroutines used in the font
  wxArrayInt*           m_lGlobalSubrsUsed;    ///< The Global SubroutinesUsed HashMaps as ArrayLists
};

#endif
